﻿using System;
using GeoAPI.Geometries;
using NetTopologySuite.Geometries;

namespace NetTopologySuite.Simplify
{
	public class DouglasPeuckerLineSimplifier
	{
		public static Coordinate[] Simplify(Coordinate[] pts, double distanceTolerance)
		{
			return new DouglasPeuckerLineSimplifier(pts)
			{
				DistanceTolerance = distanceTolerance
			}.Simplify();
		}

		public DouglasPeuckerLineSimplifier(Coordinate[] pts)
		{
			this._pts = pts;
		}

		public double DistanceTolerance { get; set; }

		public Coordinate[] Simplify()
		{
			this._usePt = new bool[this._pts.Length];
			for (int i = 0; i < this._pts.Length; i++)
			{
				this._usePt[i] = true;
			}
			this.SimplifySection(0, this._pts.Length - 1);
			CoordinateList coordinateList = new CoordinateList();
			for (int j = 0; j < this._pts.Length; j++)
			{
				if (this._usePt[j])
				{
					coordinateList.Add(new Coordinate(this._pts[j]));
				}
			}
			return coordinateList.ToCoordinateArray();
		}

		private void SimplifySection(int i, int j)
		{
			if (i + 1 == j)
			{
				return;
			}
			this._seg.P0 = this._pts[i];
			this._seg.P1 = this._pts[j];
			double num = -1.0;
			int num2 = i;
			for (int k = i + 1; k < j; k++)
			{
				double num3 = this._seg.Distance(this._pts[k]);
				if (num3 > num)
				{
					num = num3;
					num2 = k;
				}
			}
			if (num <= this.DistanceTolerance)
			{
				for (int l = i + 1; l < j; l++)
				{
					this._usePt[l] = false;
				}
				return;
			}
			this.SimplifySection(i, num2);
			this.SimplifySection(num2, j);
		}

		private readonly Coordinate[] _pts;

		private bool[] _usePt;

		private readonly LineSegment _seg = new LineSegment();
	}
}
